package com.globallogic.vkulyk.SSHTool;

import java.util.ArrayList;

import org.junit.runner.RunWith;
import org.junit.*;
import org.mockito.*;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.core.classloader.annotations.*;
import org.powermock.api.mockito.PowerMockito;

import com.jcraft.jsch.Session;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ActionsOnSocketsExecutor.class)
public class Unit_ActionsOnSocketsExecutor extends SSHToolTester {

	@Before
	public void setup() {
		// setVarsFromPropertiesFile("testData/testing.properties");
	}

	@Test
	public void shouldForAllSocketsAndActionsCallExecutorCreationWithCorrectArgsAndCallExecuteInExistingSession_whenCallExecute()
			throws Exception {
		//given
		SocketDataKeeper mockedSocketData1 = Mockito
				.mock(SocketDataKeeper.class);
		SocketDataKeeper mockedSocketData2 = Mockito
				.mock(SocketDataKeeper.class);
		ArrayList<SocketDataKeeper> socketsData = new ArrayList<SocketDataKeeper>();
		socketsData.add(mockedSocketData1);
		socketsData.add(mockedSocketData2);
		ActionDataKeeper mockedActionData1 = Mockito
				.mock(ActionDataKeeper.class);
		ActionDataKeeper mockedActionData2 = Mockito
				.mock(ActionDataKeeper.class);
		ArrayList<ActionDataKeeper> actionsData = new ArrayList<ActionDataKeeper>();
		actionsData.add(mockedActionData1);
		actionsData.add(mockedActionData2);

		ActionExecutorFactory mockedActionExecutorFactory = Mockito
				.mock(ActionExecutorFactory.class);
		ActionExecutor mockedActionExecutor = Mockito
				.mock(ActionExecutor.class);
		Session mockedSession = Mockito.mock(Session.class);

		PowerMockito
				.whenNew(ActionExecutorFactory.class)
				.withArguments(Mockito.any(SocketDataKeeper.class),
						Mockito.any(ActionDataKeeper.class))
				.thenReturn(mockedActionExecutorFactory);
		Mockito.when(
				mockedActionExecutorFactory.defineAndCreateActionExecutor())
				.thenReturn(mockedActionExecutor);
		Mockito.when(mockedActionExecutor.openSession()).thenReturn(
				mockedSession);
		Mockito.doNothing().when(mockedActionExecutor)
				.executeInExistingSession(mockedSession);

		//when
		new ActionsOnSocketsExecutor(socketsData, actionsData).execute();

		//then
		PowerMockito.verifyNew(ActionExecutorFactory.class, Mockito.times(1))
				.withArguments(Mockito.eq(mockedSocketData1),
						Mockito.eq(mockedActionData1));
		Mockito.verify(mockedActionExecutor, Mockito.times(1)).openSession();
		Mockito.verify(mockedActionExecutor, Mockito.times(4))
				.executeInExistingSession(mockedSession);
		PowerMockito.verifyNew(ActionExecutorFactory.class, Mockito.times(1))
				.withArguments(Mockito.eq(mockedSocketData1),
						Mockito.eq(mockedActionData2));
		PowerMockito.verifyNew(ActionExecutorFactory.class, Mockito.times(1))
				.withArguments(Mockito.eq(mockedSocketData2),
						Mockito.eq(mockedActionData1));
		PowerMockito.verifyNew(ActionExecutorFactory.class, Mockito.times(1))
				.withArguments(Mockito.eq(mockedSocketData2),
						Mockito.eq(mockedActionData2));
		Mockito.verify(mockedActionExecutor, Mockito.times(1)).closeSession(
				mockedSession);
	}
}
